package com.example.smartgreenhouse.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.smartgreenhouse.aliyun_bailian.BaiLianService;
import com.example.smartgreenhouse.dto.UserStatsDTO;
import com.example.smartgreenhouse.entity.UserStatistics;
import com.example.smartgreenhouse.mapper.UserAccessLogMapper;
import com.example.smartgreenhouse.mapper.UserStatisticsMapper;
import com.example.smartgreenhouse.service.SensitiveWordService;
import com.example.smartgreenhouse.service.UserService;
import com.example.smartgreenhouse.entity.User;
import com.example.smartgreenhouse.mapper.UserMapper;
import com.example.smartgreenhouse.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.Calendar;
import java.util.Date;

@Service
@Slf4j
public class UserServiceImpl implements UserService {

    private final UserMapper userMapper;

    private final UserStatisticsMapper userStatisticsMapper;

    private final UserAccessLogMapper accessLogMapper;

    private final SensitiveWordService sensitiveWordService;

    public UserServiceImpl(UserMapper userMapper, UserStatisticsMapper userStatisticsMapper, UserAccessLogMapper accessLogMapper, BaiLianService baiLianService, SensitiveWordService sensitiveWordService) {
        this.userMapper = userMapper;
        this.userStatisticsMapper = userStatisticsMapper;
        this.accessLogMapper = accessLogMapper;
        this.sensitiveWordService = sensitiveWordService;
    }

    @Override
    public User register(User user) {

        if (containsSensitiveWord(user.getUsername())) {
            throw new BusinessException("用户名包含敏感词");
        }

        // 检查用户名是否已存在
        if (userMapper.selectCount(new QueryWrapper<User>()
                .eq("username", user.getUsername())) > 0) {
            throw new BusinessException("用户名已经存在");
        }

        // 验证用户名长度
        if (user.getUsername().length() < 3 || user.getUsername().length() > 11) {
            throw new BusinessException("用户名长度需为3-11个字符");
        }

        // 验证字符组成（字母数字组合）
        if (!user.getUsername().matches("^[a-zA-Z0-9]+$")) {
            throw new BusinessException("用户名必须由字母和数字组成");
        }

        if (user.getPassword().length() < 8 || !user.getPassword().matches("^(?=.*[A-Za-z])(?=.*\\d)[A-Za-z\\d]{8,}$")) {
            throw new BusinessException("密码由数字和字母组成且必须大于8位，并且至少有一个数字或者字母");
        }

        // MD5加密密码（实际生产环境应使用更安全的加密方式）
        user.setPassword(DigestUtils.md5DigestAsHex(user.getPassword().getBytes()));
        userMapper.insert(user);
        return user;
    }

    @Override
    public User login(String username, String password) {
        User user = userMapper.selectOne(new QueryWrapper<User>()
                .eq("username", username)
                .eq("password", DigestUtils.md5DigestAsHex(password.getBytes())));
        if(user == null){
            throw new BusinessException("用户名或密码错误");
        }
        else{
            // 记录访问日志
            accessLogMapper.insertAccessLog(user.getId(), new Date());
            // 更新统计信息
            updateUserStatistics(user.getId());
        }
        return user != null ? user : null;
    }

    @Override
    public boolean updatePassword(String username, String oldPassword, String newPassword) {
        // 查找用户
        User user = userMapper.selectOne(new QueryWrapper<User>()
                .eq("username", username));
        if (user == null) {
            throw new BusinessException("用户名错误");
        }

        // 验证旧密码
        if (!DigestUtils.md5DigestAsHex(oldPassword.getBytes()).equals(user.getPassword())) {
            throw new BusinessException("旧密码输入错误");
        }

        // 验证新密码是否符合要求
        if (newPassword.length() < 8 || !newPassword.matches("^(?=.*[A-Za-z])(?=.*\\d)[A-Za-z\\d]{8,}$")) {
            throw new BusinessException("新密码由数字和字母组成且必须大于8位，并且至少有一个数字或者字母");
        }

        // 更新密码
        user.setPassword(DigestUtils.md5DigestAsHex(newPassword.getBytes()));
        return userMapper.updateById(user) > 0;
    }

    @Override
    public UserStatsDTO getUserStatistics(String username) throws BusinessException {
        User user = this.getUserByUsername(username);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }

        UserStatistics stats = userStatisticsMapper.findByUserId(user.getId());
        return stats != null ?
                new UserStatsDTO(stats.getTodayVisits(), stats.getWeeklyActiveDays(), stats.getTotalVisits()) :
                new UserStatsDTO(0, 0, 0);
    }


    @Override
    public User getUserByUsername(String username) {
        return userMapper.selectOne(new QueryWrapper<User>().eq("username", username));
    }
    /**
            * 更新用户统计信息（带事务管理）
            * @param userId 要更新的用户ID
 */

    private void updateUserStatistics(Long userId) {
        // 初始化日历实例，设置周起始为周一（中国习惯）
        Calendar calendar = Calendar.getInstance();
        calendar.setFirstDayOfWeek(Calendar.MONDAY);

        // 获取当前时间
        Date now = new Date();
        calendar.setTime(now);

        // 计算当前周数（ISO标准周数）
        int currentWeek = calendar.get(Calendar.WEEK_OF_YEAR);
        Calendar currentCal = Calendar.getInstance();
        currentCal.setTime(now);

        // 获取当前日期（清除时间部分）
        currentCal.set(Calendar.HOUR_OF_DAY, 0);
        currentCal.set(Calendar.MINUTE, 0);
        currentCal.set(Calendar.SECOND, 0);
        currentCal.set(Calendar.MILLISECOND, 0);
        Date currentDate = currentCal.getTime();

        UserStatistics stats = userStatisticsMapper.findByUserId(userId);

        if (stats == null) {
            // 新建统计记录（首次访问）
            stats = new UserStatistics();
            stats.setUserId(userId);
            stats.setTodayVisits(1);       // 当日首次访问
            stats.setWeeklyActiveDays(1);  // 本周首次活跃
            stats.setTotalVisits(1);       // 总访问次数初始化
            stats.setLastAccessDate(currentDate);
            stats.setLastWeekNumber(currentWeek);
            userStatisticsMapper.insert(stats);
        } else {
            // 判断是否新的一天（最后访问日期与当前日期不同）
            boolean isNewDay = !currentDate.equals(stats.getLastAccessDate());



            // 判断是否新的周（存储周数与当前周数不同）
            boolean isNewWeek = currentWeek != stats.getLastWeekNumber();

            // 总访问次数递增
            stats.setTotalVisits(stats.getTotalVisits() + 1);

            // 处理周活跃天数
            if (isNewWeek) {
                // 新周重置为1天
                stats.setWeeklyActiveDays(1);
                stats.setLastWeekNumber(currentWeek);
            } else if (isNewDay) {
                // 同一周内的新天，天数+1
                stats.setWeeklyActiveDays(stats.getWeeklyActiveDays() + 1);
            }

            // 处理日访问次数
            if (isNewDay) {
                // 新天重置为1次
                stats.setTodayVisits(1);
                stats.setLastAccessDate(currentDate);
            } else {
                // 同一天次数递增
                stats.setTodayVisits(stats.getTodayVisits() + 1);
            }

            // 更新数据库记录
            userStatisticsMapper.update(stats);
        }
    }

    private boolean containsSensitiveWord(String text) {
        return sensitiveWordService.getActiveWords().stream()
                .anyMatch(word -> text.toLowerCase().contains(word.toLowerCase()));
    }


}